import { ModernBaseService } from './base/ModernBaseService';
import { BagRepository, PlayerBagData, BagOperationResult, BagStatistics } from '../repository/BagRepository';
import { Item, ItemCreateConfig } from '../domain/entities/Item';
import { Player } from '../domain/entities/Player';
import { ItemType } from '../shared/face/enums';
import { BagFullError, ItemNotFoundError, InsufficientItemError } from '../domain/errors/BagError';
import { DIContainer } from '../infrastructure/di';

/**
 * 现代化背包服务类
 * 完全重构的背包服务，使用Entity和Repository模式
 * 职责：
 * 1. 背包业务逻辑处理
 * 2. 物品使用和管理
 * 3. 背包整理和查询
 * 4. 事务性操作保证
 */
export class ModernBagService extends ModernBaseService {
    private bagRepository: BagRepository;

    constructor(container?: DIContainer) {
        super(container);
        this.bagRepository = new BagRepository(container);
    }

    /**
     * 服务初始化
     */
    protected async onInit(): Promise<void> {
        await this.bagRepository.init();
        this.log('ModernBagService initialized successfully');
    }

    /**
     * 服务销毁
     */
    protected async onDestroy(): Promise<void> {
        await this.bagRepository.destroy();
        this.log('ModernBagService destroyed successfully');
    }

    /**
     * 添加物品到背包
     * @param playerId 玩家ID
     * @param itemConfig 物品配置
     * @returns 添加结果
     */
    async addItem(playerId: string, itemConfig: ItemCreateConfig): Promise<BagOperationResult> {
        return this.withPerformanceMonitoring(async () => {
            this.validateRequiredParams({ playerId, itemConfig }, ['playerId', 'itemConfig']);

            const item = Item.create(itemConfig);
            const validationResult = item.validate();
            if (!validationResult.isValid) {
                throw new Error(`Invalid item: ${validationResult.errors.map((e: any) => e.message).join(', ')}`);
            }

            try {
                const result = await this.bagRepository.addItemToBag(playerId, item);
                
                // 如果添加成功，触发相关事件
                if (result.success) {
                    await this.onItemAdded(playerId, item, result.addedCount || 0);
                }

                return result;
            } catch (error) {
                if ((error as any).message === '背包已满') {
                    throw new BagFullError();
                }
                throw error;
            }
        }, 'addItem');
    }

    /**
     * 从背包移除物品
     * @param playerId 玩家ID
     * @param itemId 物品ID
     * @param count 移除数量
     * @returns 移除结果
     */
    async removeItem(playerId: string, itemId: string, count: number): Promise<BagOperationResult> {
        return this.withPerformanceMonitoring(async () => {
            this.validateRequiredParams({ playerId, itemId, count }, ['playerId', 'itemId', 'count']);

            if (count <= 0) {
                throw new Error('Remove count must be positive');
            }

            // 检查物品是否存在
            const existingItem = await this.bagRepository.findItemInBag(playerId, itemId);
            if (!existingItem) {
                throw new ItemNotFoundError(itemId);
            }

            if (existingItem.count < count) {
                throw new InsufficientItemError(existingItem.name, count, existingItem.count);
            }

            const result = await this.bagRepository.removeItemFromBag(playerId, itemId, count);
            
            // 如果移除成功，触发相关事件
            if (result.success) {
                await this.onItemRemoved(playerId, existingItem, result.removedCount || 0);
            }

            return result;
        }, 'removeItem');
    }

    /**
     * 使用物品
     * @param playerId 玩家ID
     * @param itemId 物品ID
     * @param count 使用数量
     * @returns 使用结果
     */
    async useItem(playerId: string, itemId: string, count: number = 1): Promise<ItemUseResult> {
        return this.withPerformanceMonitoring(async () => {
            this.validateRequiredParams({ playerId, itemId }, ['playerId', 'itemId']);

            // 检查物品是否存在
            const item = await this.bagRepository.findItemInBag(playerId, itemId);
            if (!item) {
                throw new ItemNotFoundError(itemId);
            }

            if (!item.usable) {
                throw new Error(`Item ${item.name} is not usable`);
            }

            if (item.count < count) {
                throw new InsufficientItemError(item.name, count, item.count);
            }

            // 使用物品
            const useResult = item.use(count);
            if (!useResult.success) {
                throw new Error(useResult.message);
            }

            // 从背包中移除已使用的物品
            await this.bagRepository.removeItemFromBag(playerId, itemId, count);

            // 应用物品效果
            const effectResult = await this.applyItemEffect(playerId, item, useResult.effect, count);

            return {
                success: true,
                message: useResult.message,
                effect: useResult.effect,
                appliedEffect: effectResult
            };
        }, 'useItem');
    }

    /**
     * 整理背包
     * @param playerId 玩家ID
     * @returns 整理结果
     */
    async organizeBag(playerId: string): Promise<BagOperationResult> {
        return this.withPerformanceMonitoring(async () => {
            this.validateRequiredParams({ playerId }, ['playerId']);

            const result = await this.bagRepository.organizeBag(playerId);
            
            if (result.success) {
                await this.onBagOrganized(playerId);
            }

            return result;
        }, 'organizeBag');
    }

    /**
     * 获取背包信息
     * @param playerId 玩家ID
     * @returns 背包数据
     */
    async getBagInfo(playerId: string): Promise<PlayerBagData> {
        return this.cached(`bag_info_${playerId}`, async () => {
            this.validateRequiredParams({ playerId }, ['playerId']);
            return await this.bagRepository.getPlayerBag(playerId);
        }, 60000); // 缓存1分钟
    }

    /**
     * 获取背包统计信息
     * @param playerId 玩家ID
     * @returns 统计信息
     */
    async getBagStatistics(playerId: string): Promise<BagStatistics> {
        return this.cached(`bag_stats_${playerId}`, async () => {
            this.validateRequiredParams({ playerId }, ['playerId']);
            return await this.bagRepository.getBagStatistics(playerId);
        }, 300000); // 缓存5分钟
    }

    /**
     * 查找背包中的物品
     * @param playerId 玩家ID
     * @param itemId 物品ID
     * @param itemType 物品类型（可选）
     * @returns 物品实体
     */
    async findItem(playerId: string, itemId: string, itemType?: ItemType): Promise<Item | null> {
        this.validateRequiredParams({ playerId, itemId }, ['playerId', 'itemId']);
        return await this.bagRepository.findItemInBag(playerId, itemId, itemType?.toString());
    }

    /**
     * 检查是否拥有指定物品
     * @param playerId 玩家ID
     * @param itemId 物品ID
     * @param requiredCount 需要的数量
     * @returns 是否拥有
     */
    async hasItem(playerId: string, itemId: string, requiredCount: number = 1): Promise<boolean> {
        const item = await this.findItem(playerId, itemId);
        return item ? item.count >= requiredCount : false;
    }

    /**
     * 扩展背包容量
     * @param playerId 玩家ID
     * @param additionalSize 增加的容量
     * @returns 扩展结果
     */
    async expandBag(playerId: string, additionalSize: number): Promise<{
        success: boolean;
        message: string;
        newSize: number;
        oldSize: number;
    }> {
        return this.withPerformanceMonitoring(async () => {
            this.validateRequiredParams({ playerId, additionalSize }, ['playerId', 'additionalSize']);

            if (additionalSize <= 0) {
                throw new Error('Additional size must be positive');
            }

            const bagData = await this.bagRepository.getPlayerBag(playerId);
            const oldSize = bagData.maxSize;
            const newSize = oldSize + additionalSize;

            // 检查最大容量限制
            const maxAllowedSize = 500; // 最大允许的背包容量
            if (newSize > maxAllowedSize) {
                throw new Error(`Bag size cannot exceed ${maxAllowedSize}`);
            }

            bagData.maxSize = newSize;
            await this.bagRepository.savePlayerBag(playerId, bagData);

            // 清除相关缓存
            this.clearCache(`bag_info_${playerId}`);
            this.clearCache(`bag_stats_${playerId}`);

            return {
                success: true,
                message: `背包容量已扩展至 ${newSize}`,
                newSize,
                oldSize
            };
        }, 'expandBag');
    }

    /**
     * 批量添加物品
     * @param playerId 玩家ID
     * @param items 物品配置列表
     * @returns 批量添加结果
     */
    async batchAddItems(playerId: string, items: ItemCreateConfig[]): Promise<BatchItemResult> {
        return this.batchProcess(items, async (itemConfig, index) => {
            return await this.addItem(playerId, itemConfig);
        }, 'batchAddItems');
    }

    /**
     * 批量移除物品
     * @param playerId 玩家ID
     * @param operations 移除操作列表
     * @returns 批量移除结果
     */
    async batchRemoveItems(playerId: string, operations: RemoveOperation[]): Promise<BatchItemResult> {
        return this.batchProcess(operations, async (operation, index) => {
            return await this.removeItem(playerId, operation.itemId, operation.count);
        }, 'batchRemoveItems');
    }

    /**
     * 交换物品位置
     * @param playerId 玩家ID
     * @param fromIndex 源位置
     * @param toIndex 目标位置
     * @returns 交换结果
     */
    async swapItems(playerId: string, fromIndex: number, toIndex: number): Promise<{
        success: boolean;
        message: string;
    }> {
        return this.withPerformanceMonitoring(async () => {
            this.validateRequiredParams({ playerId, fromIndex, toIndex }, ['playerId', 'fromIndex', 'toIndex']);

            const bagData = await this.bagRepository.getPlayerBag(playerId);
            
            if (fromIndex < 0 || fromIndex >= bagData.items.length) {
                throw new Error('Invalid from index');
            }
            
            if (toIndex < 0 || toIndex >= bagData.items.length) {
                throw new Error('Invalid to index');
            }

            if (fromIndex === toIndex) {
                return {
                    success: true,
                    message: 'No change needed'
                };
            }

            // 交换物品位置
            [bagData.items[fromIndex], bagData.items[toIndex]] = [bagData.items[toIndex], bagData.items[fromIndex]];
            
            await this.bagRepository.savePlayerBag(playerId, bagData);

            return {
                success: true,
                message: '物品位置交换成功'
            };
        }, 'swapItems');
    }

    /**
     * 应用物品效果
     * @param playerId 玩家ID
     * @param item 物品
     * @param effect 物品效果
     * @param count 使用数量
     * @returns 效果应用结果
     */
    private async applyItemEffect(playerId: string, item: Item, effect: any, count: number): Promise<any> {
        if (!effect) return null;

        try {
            const player = this.sdk.getPlayerById(playerId);
            if (!player) {
                throw new Error(`Player ${playerId} not found`);
            }

            switch (effect.type) {
                case 'heal':
                    return await this.applyHealEffect(player, effect, count);
                case 'buff':
                    return await this.applyBuffEffect(player, effect, count);
                case 'exp':
                    return await this.applyExpEffect(player, effect, count);
                default:
                    this.log(`Unknown effect type: ${effect.type}`, 'warn');
                    return null;
            }
        } catch (error) {
            this.log(`Failed to apply item effect: ${(error as any).message}`, 'error');
            return { success: false, error: (error as any).message };
        }
    }

    /**
     * 应用治疗效果
     */
    private async applyHealEffect(player: any, effect: any, count: number): Promise<any> {
        const healAmount = effect.value * count;
        // 这里需要根据实际的玩家系统来实现
        // player.heal(healAmount);
        return { type: 'heal', amount: healAmount };
    }

    /**
     * 应用增益效果
     */
    private async applyBuffEffect(player: any, effect: any, count: number): Promise<any> {
        // 这里需要根据实际的增益系统来实现
        return { type: 'buff', effect: effect, duration: effect.duration };
    }

    /**
     * 应用经验效果
     */
    private async applyExpEffect(player: any, effect: any, count: number): Promise<any> {
        const expAmount = effect.value * count;
        // 这里需要根据实际的经验系统来实现
        // player.addExperience(expAmount);
        return { type: 'exp', amount: expAmount };
    }

    /**
     * 物品添加事件处理
     */
    private async onItemAdded(playerId: string, item: Item, count: number): Promise<void> {
        this.log(`Item added: ${item.name} x${count} for player ${playerId}`);
        // 清除相关缓存
        this.clearCache(`bag_info_${playerId}`);
        this.clearCache(`bag_stats_${playerId}`);
        
        // 可以在这里添加任务进度更新等逻辑
        // await this.updateTaskProgress(playerId, 'COLLECT_ITEM', count);
    }

    /**
     * 物品移除事件处理
     */
    private async onItemRemoved(playerId: string, item: Item, count: number): Promise<void> {
        this.log(`Item removed: ${item.name} x${count} for player ${playerId}`);
        // 清除相关缓存
        this.clearCache(`bag_info_${playerId}`);
        this.clearCache(`bag_stats_${playerId}`);
    }

    /**
     * 背包整理事件处理
     */
    private async onBagOrganized(playerId: string): Promise<void> {
        this.log(`Bag organized for player ${playerId}`);
        // 清除相关缓存
        this.clearCache(`bag_info_${playerId}`);
        this.clearCache(`bag_stats_${playerId}`);
    }
}

/**
 * 物品使用结果接口
 */
export interface ItemUseResult {
    success: boolean;
    message: string;
    effect: any;
    appliedEffect: any;
}

/**
 * 移除操作接口
 */
export interface RemoveOperation {
    itemId: string;
    count: number;
}

/**
 * 批量物品结果接口
 */
export interface BatchItemResult {
    success: boolean;
    results: BagOperationResult[];
    errors: { index: number; item: any; error: string }[];
}
